Android AMS(ATMS)的应用启动流程解析

您所在的位置:网站首页 ams android 虚拟 Android AMS(ATMS)的应用启动流程解析

Android AMS(ATMS)的应用启动流程解析

2024-07-16 04:45| 来源: 网络整理| 查看: 265

前言

在Android Q中,activity的调度和管理已经从AMS移到了ActivityTaskManagerService中(这里简称ATMS)

简介 Launcher点击应用图标:这个过程是Launcher进程中进行的,去启动应用的第一个activity。 通过binder进入ATMS:在ATMS中,为应用的第一个activity创建了ActivityRecord,找到其ActivityStack,将ActivityRecord插入到所在的TaskRecord的合适位置。最后执行到ActivityManagerInternal::startProcess。 进入AMS,请求创建应用进程:这个过程创建了ProcessRecord对象并处理保存了进程所需的各种信息。最后通过Process.start()请求创建应用进程。 Zygote创建应用进程:通过socket与zygote进程通信,fork出应用进程。 应用进程主线程-执行ActivityThread的main():在应用主线程中,执行ActivityThread的main()。 进入系统进程,绑定应用进程:创建了应用的Application,将应用进程绑定到ATMS中,由它们管理。 回到应用进程:这里主要是创建出应用第一个Activity,并执行了attach()和onCreate()。

注:AMS和ATMS服务都是在系统进程-system server进程中。 所以,整个过程 进程变化是:Launcher进程(binder)->systemserver进程(socket)->zygote进程(socket)->应用进程(binder)->systemserver进程(binder)->应用进程。  

Activity的启动过程详述

ams_app_launcher

桌面Launcher点击应用图标

Launcher点击图标,BaseDraggingActivity.java中startActivitySafely()调用了startActivity()。 这是的activity是Launcher的activity,在Launcher的进程中。

Activity中各种startActivity()调用,最终都是走到的startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options)方法的。

//Activity.java: @Override public void startActivity(Intent intent) { this.startActivity(intent, null); } @Override public void startActivity(Intent intent, @Nullable Bundle options) { if (options != null) { startActivityForResult(intent, -1, options); } else { // Note we want to go through this call for compatibility with // applications that may have overridden the method. startActivityForResult(intent, -1); } } public void startActivityForResult(@RequiresPermission Intent intent, int requestCode) { startActivityForResult(intent, requestCode, null); }

所以Launcher点击图标后这里直接从startActivityForResult()开始看,从上面可以看到requestCode值为-1。

//Activity.java: public void startActivityForResult(@RequiresPermission Intent intent, int requestCode, @Nullable Bundle options) { //mParent一般为null if (mParent == null) { options = transferSpringboardActivityOptions(options); //调用mInstrumentation.execStartActivity() //mMainThread、mInstrumentation、mToken在attach()被赋值 Instrumentation.ActivityResult ar = mInstrumentation.execStartActivity( this, mMainThread.getApplicationThread(), mToken, this, intent, requestCode, options); ...... } else { //调用mParent.startActivityFromChild(),和上面逻辑类似 } }

目前还是在Launcher进程,这里mMainThread、mInstrumentation、mToken都是在attach()被赋值。 Instrumentation监控system(主要是AM,Activity Manager)与application之间的所有交互。 mToken是IBinder对象,是Binder代理,是Android中IPC重要部分。 mMainThread是ActivityThread对象,应用的主线程。这里是Launhcer的主线程。那么什么时候被赋值的呢?attach()在哪被调用的?看到最后就知道了^v^

这里关键代码 调用了mInstrumentation.execStartActivity()。

//Instrumentation.java @UnsupportedAppUsage public ActivityResult execStartActivity( Context who, IBinder contextThread, IBinder token, Activity target, Intent intent, int requestCode, Bundle options) { IApplicationThread whoThread = (IApplicationThread) contextThread; ...... try { intent.migrateExtraStreamToClipData(); intent.prepareToLeaveProcess(who); int result = ActivityTaskManager.getService() .startActivity(whoThread, who.getBasePackageName(), intent, intent.resolveTypeIfNeeded(who.getContentResolver()), token, target != null ? target.mEmbeddedID : null, requestCode, 0, null, options); checkStartActivityResult(result, intent); } catch (RemoteException e) { throw new RuntimeException("Failure from system", e); } return null; }

这里主要看ActivityTaskManager.getService().startActivity()这个方法。ActivityTaskManager.getService()这个涉及Binder机制,可以参考 Binder机制 。 这里获取的服务名是Context.ACTIVITY_TASK_SERVICE(=activity_task),最终调用的是ActivityTaskManagerService.startActivity()方法。  

进入ATMS

通过Binder机制,由Launcher进程进入到ATMS。 ActivityTaskManagerService中的startActivity()

//ActivityTaskManagerService.java: @Override public final int startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, UserHandle.getCallingUserId()); } @Override public int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) { return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo, resultWho, requestCode, startFlags, profilerInfo, bOptions, userId, true /*validateIncomingUser*/); } int startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) { enforceNotIsolatedCaller("startActivityAsUser"); userId = getActivityStartController().checkTargetUser(userId, validateIncomingUser, Binder.getCallingPid(), Binder.getCallingUid(), "startActivityAsUser"); // TODO: Switch to user app stacks here. return getActivityStartController().obtainStarter(intent, "startActivityAsUser") .setCaller(caller) .setCallingPackage(callingPackage) .setResolvedType(resolvedType) .setResultTo(resultTo) .setResultWho(resultWho) .setRequestCode(requestCode) .setStartFlags(startFlags) .setProfilerInfo(profilerInfo) .setActivityOptions(bOptions) .setMayWait(userId) .execute(); }

ATMS中的startActivity(),最终调用了ActivityStarter中的execute()。

//ActivityStarter.java: ActivityStarter setMayWait(int userId) { mRequest.mayWait = true; mRequest.userId = userId; return this; } int execute() { try { // TODO(b/64750076): Look into passing request directly to these methods to allow // for transactional diffs and preprocessing. if (mRequest.mayWait) { return startActivityMayWait(mRequest.caller, mRequest.callingUid, mRequest.callingPackage, mRequest.realCallingPid, mRequest.realCallingUid, mRequest.intent, mRequest.resolvedType, mRequest.voiceSession, mRequest.voiceInteractor, mRequest.resultTo, mRequest.resultWho, mRequest.requestCode, mRequest.startFlags, mRequest.profilerInfo, mRequest.waitResult, mRequest.globalConfig, mRequest.activityOptions, mRequest.ignoreTargetSecurity, mRequest.userId, mRequest.inTask, mRequest.reason, mRequest.allowPendingRemoteAnimationRegistryLookup, mRequest.originatingPendingIntent, mRequest.allowBackgroundActivityStart); } else { ...... } } finally { onExecutionComplete(); } }

在setMayWait()中,mRequest.mayWait = true;,因此走到startActivityMayWait()。

//ActivityStarter.java: private int startActivityMayWait(IApplicationThread caller, int callingUid, String callingPackage, int requestRealCallingPid, int requestRealCallingUid, Intent intent, String resolvedType, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, WaitResult outResult, Configuration globalConfig, SafeActivityOptions options, boolean ignoreTargetSecurity, int userId, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) { ...... ActivityInfo aInfo = mSupervisor.resolveActivity(intent, rInfo, startFlags, profilerInfo); synchronized (mService.mGlobalLock) { final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStack(); ...... final ActivityRecord[] outRecord = new ActivityRecord[1]; int res = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, outRecord, inTask, reason, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent, allowBackgroundActivityStart); ...... mSupervisor.getActivityMetricsLogger().notifyActivityLaunched(res, outRecord[0]); if (outResult != null) { outResult.result = res; final ActivityRecord r = outRecord[0]; ...... } return res; } } //startActivity 1 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, String reason, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) { if (TextUtils.isEmpty(reason)) { throw new IllegalArgumentException("Need to specify a reason."); } mLastStartReason = reason; mLastStartActivityTimeMs = System.currentTimeMillis(); mLastStartActivityRecord[0] = null; mLastStartActivityResult = startActivity(caller, intent, ephemeralIntent, resolvedType, aInfo, rInfo, voiceSession, voiceInteractor, resultTo, resultWho, requestCode, callingPid, callingUid, callingPackage, realCallingPid, realCallingUid, startFlags, options, ignoreTargetSecurity, componentSpecified, mLastStartActivityRecord, inTask, allowPendingRemoteAnimationRegistryLookup, originatingPendingIntent, allowBackgroundActivityStart); if (outActivity != null) { // mLastStartActivityRecord[0] is set in the call to startActivity above. outActivity[0] = mLastStartActivityRecord[0]; } return getExternalResult(mLastStartActivityResult); } //startActivity 2 private int startActivity(IApplicationThread caller, Intent intent, Intent ephemeralIntent, String resolvedType, ActivityInfo aInfo, ResolveInfo rInfo, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor, IBinder resultTo, String resultWho, int requestCode, int callingPid, int callingUid, String callingPackage, int realCallingPid, int realCallingUid, int startFlags, SafeActivityOptions options, boolean ignoreTargetSecurity, boolean componentSpecified, ActivityRecord[] outActivity, TaskRecord inTask, boolean allowPendingRemoteAnimationRegistryLookup, PendingIntentRecord originatingPendingIntent, boolean allowBackgroundActivityStart) { ....... ActivityRecord r = new ActivityRecord(mService, callerApp, callingPid, callingUid, callingPackage, intent, resolvedType, aInfo, mService.getGlobalConfiguration(), resultRecord, resultWho, requestCode, componentSpecified, voiceSession != null, mSupervisor, checkedOptions, sourceRecord); if (outActivity != null) { outActivity[0] = r; } ...... final ActivityStack stack = mRootActivityContainer.getTopDisplayFocusedStac


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3